<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

/**
 * ThinkPHP Widget类 抽象类
 * @category   Think
 * @package  Think
 * @subpackage  Core
 * @author liu21st <liu21st@gmail.com>
 */
abstract class Widget {

	// 使用的模板引擎 每个Widget可以单独配置不受系统影响
	protected $template =  '';

	/**
	 * 渲染输出 render方法是Widget唯一的接口
	 * 使用字符串返回 不能有任何输出
	 * @access public
	 * @param mixed $data  要渲染的数据
	 * @return string
	 */
	abstract public function render($data);

	/**
	 * 渲染模板输出 供render方法内部调用
	 * @access public
	 * @param string $templateFile  模板文件
	 * @param mixed $var  模板变量
	 * @return string
	 */
	protected function renderFile($templateFile='',$var='') {
		ob_start();
		ob_implicit_flush(0);
		if(!file_exists_case($templateFile)){
			// 自动定位模板文件
			$name   = substr(get_class($this),0,-6);
			$filename   =  empty($templateFile)?$name:$templateFile;
			$templateFile = BASE_LIB_PATH.'Widget/'.$name.'/'.$filename.C('TMPL_TEMPLATE_SUFFIX');
			if(!file_exists_case($templateFile))
			throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$templateFile.']');
		}
		$template   =  strtolower($this->template?$this->template:(C('TMPL_ENGINE_TYPE')?C('TMPL_ENGINE_TYPE'):'php'));
		if('php' == $template) {
			// 使用PHP模板
			if(!empty($var)) extract($var, EXTR_OVERWRITE);
			// 直接载入PHP模板
			include $templateFile;
		}elseif('think'==$template){ // 采用Think模板引擎
			if($this->checkCache($templateFile)) { // 缓存有效
				// 分解变量并载入模板缓存
				extract($var, EXTR_OVERWRITE);
				//载入模版缓存文件
				include C('CACHE_PATH').md5($templateFile).C('TMPL_CACHFILE_SUFFIX');
			}else{
				$tpl = Think::instance('ThinkTemplate');
				// 编译并加载模板文件
				$tpl->fetch($templateFile,$var);
			}
		}else{
			$class   = 'Template'.ucwords($template);
			if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) {
				// 内置驱动
				$path = CORE_PATH;
			}else{ // 扩展驱动
				$path = EXTEND_PATH;
			}
			require_cache($path.'Driver/Template/'.$class.'.class.php');
			$tpl   =  new $class;
			$tpl->fetch($templateFile,$var);
		}
		$content = ob_get_clean();
		return $content;
	}

	/**
	 * 检查缓存文件是否有效
	 * 如果无效则需要重新编译
	 * @access public
	 * @param string $tmplTemplateFile  模板文件名
	 * @return boolen
	 */
	protected function checkCache($tmplTemplateFile) {
		if (!C('TMPL_CACHE_ON')) // 优先对配置设定检测
		return false;
		$tmplCacheFile = C('CACHE_PATH').md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX');
		if(!is_file($tmplCacheFile)){
			return false;
		}elseif (filemtime($tmplTemplateFile) > filemtime($tmplCacheFile)) {
			// 模板文件如果有更新则缓存需要更新
			return false;
		}elseif (C('TMPL_CACHE_TIME') != 0 && time() > filemtime($tmplCacheFile)+C('TMPL_CACHE_TIME')) {
			// 缓存是否在有效期
			return false;
		}
		// 缓存有效
		return true;
	}
}